package com.common.client;

import java.util.ArrayList;
import java.util.HashMap;

import com.common.shared.SharedClass;
import com.smartgwt.client.data.Record;
import com.smartgwt.client.types.ListGridFieldType;
import com.smartgwt.client.util.SC;
import com.smartgwt.client.widgets.events.ClickEvent;
import com.smartgwt.client.widgets.events.DoubleClickEvent;
import com.smartgwt.client.widgets.events.DoubleClickHandler;
import com.smartgwt.client.widgets.grid.ListGrid;
import com.smartgwt.client.widgets.grid.ListGridField;
import com.smartgwt.client.widgets.grid.ListGridRecord;
import com.smartgwt.client.widgets.grid.events.SelectionChangedHandler;
import com.smartgwt.client.widgets.grid.events.SelectionEvent;
import com.smartgwt.client.widgets.layout.VLayout;
import com.smartgwt.client.widgets.menu.Menu;
import com.smartgwt.client.widgets.menu.MenuItem;
import com.smartgwt.client.widgets.menu.events.ClickHandler;
import com.smartgwt.client.widgets.menu.events.MenuItemClickEvent;
import com.smartgwt.client.widgets.toolbar.ToolStrip;
import com.smartgwt.client.widgets.toolbar.ToolStripButton;

public abstract class PSharedClassList extends VLayout implements
		WindowResultObject {

	protected HashMap<Long, SharedClass> mapSharedClasses = new HashMap<Long, SharedClass>();
	protected ListGrid lgSharedClass;

	public static final String ICON_ADD = "demoApp/icon_add.png";
	public static final String ICON_EDIT = "demoApp/icon_edit.png";
	public static final String ICON_DELETE = "demoApp/icon_delete.png";
	public static final String ICON_REFRESH = "icons/24/img_refresh.jpg";

	public static final String CAPTION_ADD = "დამატება";
	public static final String CAPTION_EDIT = "შეცვლა";
	public static final String CAPTION_DELETE = "წაშლა";
	public static final String CAPTION_REFRESH = "განახლება";

	private MenuItem miAdd;
	private MenuItem miEdit;
	private MenuItem miDelete;
	private MenuItem miRefresh;

	private ToolStripButton ttbAdd;
	private ToolStripButton ttbEdit;
	private ToolStripButton ttbDelete;
	private ToolStripButton ttbRefresh;

	protected ToolStrip toolStrip;
	protected Menu menu;

	private boolean readOnly;

	public PSharedClassList() {
		lgSharedClass = new ListGrid();
		ListGridField lgfId = new ListGridField("id", "ID", 50);
		lgfId.setType(ListGridFieldType.INTEGER);
		ListGridField lgfName = new ListGridField("name", "დასახელება", 500);
		ListGridField[] additionalFields = getAdditionalFields();
		ListGridField[] fields = new ListGridField[additionalFields.length + 2];
		fields[0] = lgfId;
		fields[1] = lgfName;
		for (int i = 0; i < additionalFields.length; i++) {
			fields[i + 2] = additionalFields[i];
		}
		lgSharedClass.setFields(fields);

		VLayout hl = new VLayout();
		hl.setWidth100();
		hl.setHeight100();
		lgSharedClass.setWidth100();
		lgSharedClass.setHeight("95%");

		lgSharedClass.addSelectionChangedHandler(new SelectionChangedHandler() {
			@Override
			public void onSelectionChanged(SelectionEvent event) {
				Record rec = event.getSelectedRecord();
				if (rec == null)
					return;
				enableEnableAll();

			}
		});

		toolStrip = new ToolStrip();
		toolStrip.setWidth100();
		toolStrip.setHeight("5%");

		menu = new Menu();

		miAdd = new MenuItem(CAPTION_ADD, ICON_ADD);
		menu.addItem(miAdd);
		miEdit = new MenuItem(CAPTION_EDIT, ICON_EDIT);
		menu.addItem(miEdit);
		miDelete = new MenuItem(CAPTION_DELETE, ICON_DELETE);
		menu.addItem(miDelete);
		miRefresh = new MenuItem(CAPTION_REFRESH, ICON_REFRESH);
		menu.addItem(miRefresh);

		lgSharedClass.setContextMenu(menu);

		toolStrip.addSeparator();
		toolStrip.addSeparator();
		toolStrip.addSeparator();
		ttbAdd = new ToolStripButton(CAPTION_ADD, ICON_ADD);
		toolStrip.addButton(ttbAdd);
		ttbEdit = new ToolStripButton(CAPTION_EDIT, ICON_EDIT);
		toolStrip.addButton(ttbEdit);
		ttbDelete = new ToolStripButton(CAPTION_DELETE, ICON_DELETE);
		toolStrip.addButton(ttbDelete);
		ttbRefresh = new ToolStripButton(CAPTION_REFRESH, ICON_REFRESH);
		toolStrip.addButton(ttbRefresh);

		hl.addMember(toolStrip);
		hl.addMember(lgSharedClass);
		this.addMember(hl);
		disableAllActions();

		miRefresh.addClickHandler(new ClickHandler() {

			@Override
			public void onClick(MenuItemClickEvent event) {
				refreshByType();

			}
		});

		ClickHandler addEdithandler = new ClickHandler() {

			@Override
			public void onClick(MenuItemClickEvent event) {
				addEditClassifier(event.getItem().equals(miAdd));
			}
		};

		miAdd.addClickHandler(addEdithandler);
		miEdit.addClickHandler(addEdithandler);
		ttbRefresh
				.addClickHandler(new com.smartgwt.client.widgets.events.ClickHandler() {

					@Override
					public void onClick(ClickEvent event) {
						refreshByType();

					}
				});
		com.smartgwt.client.widgets.events.ClickHandler taddEdithandler = new com.smartgwt.client.widgets.events.ClickHandler() {

			@Override
			public void onClick(ClickEvent event) {
				addEditClassifier(event.getSource().equals(ttbAdd));
			}
		};

		ttbAdd.addClickHandler(taddEdithandler);
		ttbEdit.addClickHandler(taddEdithandler);

		lgSharedClass.addDoubleClickHandler(new DoubleClickHandler() {

			@Override
			public void onDoubleClick(DoubleClickEvent event) {
				addEditClassifier(false);

			}
		});

	}

	protected abstract int getRefreshType();

	protected abstract void refreshByType();

	protected void enableAdd() {
		miAdd.setEnabled(true);
		ttbAdd.setDisabled(false);
		if (readOnly) {
			disableAllActions();
		}
	}

	protected void enableEnableAll() {
		miEdit.setEnabled(true);
		miDelete.setEnabled(true);

		ttbEdit.setDisabled(false);
		ttbDelete.setDisabled(false);
		if (readOnly) {
			disableAllActions();
		}
	}

	protected void disableAllActions() {
		miAdd.setEnabled(false);
		miEdit.setEnabled(false);
		miDelete.setEnabled(false);

		ttbAdd.setDisabled(true);
		ttbEdit.setDisabled(true);
		ttbDelete.setDisabled(true);
	}

	protected abstract SharedClass createNewSharedClass();

	protected abstract void doAddEditOperation(boolean add, SharedClass cl);

	public void setData(ArrayList<SharedClass> sharedClasses) {
		mapSharedClasses.clear();
		disableAllActions();
		lgSharedClass.setRecords(new ListGridRecord[0]);

		ArrayList<ListGridRecord> records = new ArrayList<ListGridRecord>();
		for (SharedClass sharedClass : sharedClasses) {
			records.add(setSharedClass(sharedClass));
			mapSharedClasses.put(sharedClass.getIdVal(), sharedClass);
		}
		lgSharedClass.setRecords(records.toArray(new ListGridRecord[0]));
		enableAdd();
	}

	protected ListGridRecord setSharedClass(SharedClass sharedClass) {
		ListGridRecord ret = new ListGridRecord();
		ret.setAttribute("id", sharedClass.getIdVal());
		ret.setAttribute("name", sharedClass.getTextVal());
		setOtherValues(sharedClass, ret);
		return ret;
	}

	private void addEditClassifier(boolean add) {
		SharedClass cl = null;
		if (!add) {
			ListGridRecord rec = lgSharedClass.getSelectedRecord();
			if (rec == null) {
				SC.say("გთხოვთ მონიშნოთ ჩანაწერი!!!");
				return;
			}
			try {
				long id = -1;
				try {
					id = Long.parseLong(rec.getAttribute("id").toString());
				} catch (Exception e) {
					// TODO: handle exception
				}
				cl = mapSharedClasses.get(id);
			} catch (Exception e) {
				SC.say("გთხოვთ მონიშნოთ ჩანაწერი!!!");
				return;
			}

		} else {
			cl = createNewSharedClass();
		}

		if (cl == null) {
			SC.say("გთხოვთ მონიშნოთ ჩანაწერი!!!");
			return;
		}
		doAddEditOperation(add, cl);
		// WAddEditClassifier.showWindow(cl, this);
	}

	protected ListGridField[] getAdditionalFields() {
		return new ListGridField[] {};
	}

	protected void setOtherValues(SharedClass sharedClass, ListGridRecord ret) {

	}

	@Override
	public void destroy() {
		mapSharedClasses.clear();
		lgSharedClass.clear();
		lgSharedClass.setData(new Record[0]);
		lgSharedClass.destroy();
		super.destroy();
	}

	public boolean isReadOnly() {
		return readOnly;
	}

	public void setReadOnly(boolean readOnly) {
		this.readOnly = readOnly;
		miRefresh.setEnabled(!readOnly);
		ttbRefresh.setDisabled(readOnly);
	}

}
